﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using EnvDTE;
using tomenglertde.SetupProject.View;
using tomenglertde.SetupProject.ViewModel;
using System.Reflection;
using System.IO;
using System.Globalization;

namespace tomenglertde.SetupProjectTuner
{
    /// <summary>
    /// This class implements the tool window exposed by this package and hosts a user control.
    ///
    /// In Visual Studio tool windows are composed of a frame (implemented by the shell) and a pane, 
    /// usually implemented by the package implementer.
    ///
    /// This class derives from the ToolWindowPane class provided from the MPF in order to use its 
    /// implementation of the IVsUIElementPane interface.
    /// </summary>
    [Guid("61af6f7c-fb40-4304-ac78-ea1ef03baefb")]
    public class ToolWindow : ToolWindowPane
    {
        private DTE _dte;

        /// <summary>
        /// Standard constructor for the tool window.
        /// </summary>
        public ToolWindow() :
            base(null)
        {
            // Set the window title reading it from the resources.
            this.Caption = Resources.ToolWindowTitle;
            // Set the image that will appear on the tab of the window frame
            // when docked with an other window
            // The resource ID correspond to the one defined in the resx file
            // while the Index is the offset in the bitmap strip. Each image in
            // the strip being 16x16.
            this.BitmapResourceID = 301;
            this.BitmapIndex = 1;
        }

        protected override void OnCreate()
        {
            base.OnCreate();

            AppDomain.CurrentDomain.AssemblyResolve += AppDomain_AssemblyResolve;

            _dte = (DTE)GetService(typeof(DTE));

            // This is the user control hosted by the tool window; Note that, even if this class implements IDisposable,
            // we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on 
            // the object returned by the Content property.
            var projectList = new ProjectList();
            projectList.Loaded += (sender, _) => ((ProjectList)sender).DataContext = new SolutionViewModel(_dte.Solution);

            base.Content = projectList;
        }

        protected override void OnClose()
        {
            base.OnClose();

            AppDomain.CurrentDomain.AssemblyResolve -= AppDomain_AssemblyResolve;
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFile", Justification = "Must run in the AppDomain of VS, so all referenced assemblies are outside the probing path!")]
        private static Assembly AppDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            var folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            if (folder == null)
                return null;
            if (args.Name == null)
                return null;

            var assemblyName = args.Name.Split(',')[0];

            if (!assemblyName.StartsWith("SetupProject."))
                return null;

            var filePath = Path.Combine(folder, assemblyName + ".dll");

            return File.Exists(filePath) ? Assembly.LoadFile(filePath) : null;
        }

        private void MessageBox(string message)
        {
            IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
            Guid clsid = Guid.Empty;
            int result;
            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(
                       0,
                       ref clsid,
                       "SetupProjectTuner",
                       message,
                       string.Empty,
                       0,
                       OLEMSGBUTTON.OLEMSGBUTTON_OK,
                       OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                       OLEMSGICON.OLEMSGICON_INFO,
                       0,        // false
                       out result));
        }
    }
}
